﻿using UnityEngine;

namespace PnFramework.Unity
{
    public struct DirInputEvent
    {
        public int hor, ver;
    }
    public class InputMgr
    {
        /// <summary>
        /// 方向输入事件
        /// </summary>
        public const string DirInput = "DirInput";
        /// <summary>
        /// 方向输入数据
        /// </summary>
        private DirInputEvent mDirInput;
        /// <summary>
        /// 用于表示输入状态
        /// </summary>
        private enum E_InputState { Down, Up, Hold }
        //按键集成
        private readonly KeyCode[] mUpKeys = { KeyCode.W, KeyCode.UpArrow };
        private readonly KeyCode[] mDownKeys = { KeyCode.S, KeyCode.DownArrow };
        private readonly KeyCode[] mLeftKeys = { KeyCode.A, KeyCode.LeftArrow };
        private readonly KeyCode[] mRightKeys = { KeyCode.D, KeyCode.RightArrow };
        /// <summary>
        /// 更新函数
        /// </summary>
        public void Update()
        {
            CheckMoveDir(BindableInput(mLeftKeys), BindableInput(mRightKeys), ref mDirInput.hor);
            CheckMoveDir(BindableInput(mDownKeys), BindableInput(mUpKeys), ref mDirInput.ver);

            //mDirInputEvent?.Invoke(mInputX, mInputY);

            //我们可以看到在输入管理器和弹幕管理器中已经有了事件这个概念 我们只需要将这些碎片事件 替换成 事件系统即可
            //在输入管理器中，因为方向轴的输入是分两组的，我们可以在外部定义一个结构体用于携带参数（看上面） 然后直接在Update中触发事件即可 在使用中（跳到Player脚本）            

            EventMgr.Instance.Trigger(DirInput, mDirInput);
        }
        /// <summary>
        /// 检测移动方向
        /// </summary>
        /// <param name="negativeState">负向量状态 => [-1]</param>
        /// <param name="positiveState">正向量状态 => [+1]</param>
        /// <param name="moveDir">返回的向量值</param>
        private void CheckMoveDir(E_InputState negativeState, E_InputState positiveState, ref int inputDir)
        {
            if (negativeState == E_InputState.Down) inputDir = -1;
            else if (positiveState == E_InputState.Down) inputDir = 1;
            else if (negativeState == E_InputState.Up) inputDir = positiveState == E_InputState.Hold ? 1 : 0;
            else if (positiveState == E_InputState.Up) inputDir = negativeState == E_InputState.Hold ? -1 : 0;
        }
        /// <summary>
        /// 绑定按键输入【多情况】
        /// </summary>
        /// <param name="keys">按键数组</param>
        private E_InputState BindableInput(KeyCode[] keys)
        {
            for (int i = 0; i < keys.Length; i++)
            {
                if (Input.GetKeyDown(keys[i])) return E_InputState.Down;
                if (Input.GetKey(keys[i])) return E_InputState.Hold;
                if (Input.GetKeyUp(keys[i])) return E_InputState.Up;
            }
            return E_InputState.Up;
        }
    }
}